﻿//Copyright (C) 2009  Jaco (ScionBot.com)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Scion.External;
using System.Drawing;

namespace Scion.Core
{
    /// <summary>
    /// Our offscreen manager. This involves the window manipulation required in order to recieve the RS
    /// canvas offscreen. Alot of work has gone into this, so enjoy what you get.
    /// </summary>
    public class Offscreen
    {
        public IntPtr loaderHandle = IntPtr.Zero;
        public int loaderExStyle = 0;
        public int loaderExTransparentStyle = 0;
        public int loaderStyle = 0;

        Stub super = null;
   
        public Offscreen(Stub sender)
        {
            super = sender;
        }

        public void GetHandle()
        {
            loaderHandle = API.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "SunAwtFrame", "Bot " + super.botNumber);
        }

        public void TransparentWindow(bool mode)
        {
            //return;
            if (mode)
            {
                //Save our old style, so we can revert back to it if needed.
                loaderExStyle = API.GetWindowLong(loaderHandle, (int)WM.M.GWL_EXSTYLE);
                //Save new style
                loaderExTransparentStyle = loaderExStyle | (int)WM.M.WS_EX_LAYERED;
                //Apply a layered property.
                API.SetWindowLong(loaderHandle, (int)WM.M.GWL_EXSTYLE, loaderExTransparentStyle);
                //Apply our transparent attribute with 0 opacity.
                API.SetLayeredWindowAttributes(loaderHandle, 0, 1, (int)WM.M.LWA_ALPHA);
                //Finally, send a message to the window to re-paint.
                API.SendMessage(loaderHandle, (int)WM.M.WM_PAINT, 0, 0);
            }
            else
            {
                //Revert to old window style...
                API.SetWindowLong(loaderHandle, (int)WM.M.GWL_EXSTYLE, loaderExStyle);
                //Opaque the window.
                API.SetLayeredWindowAttributes(loaderHandle, 0, 255, (int)WM.M.LWA_ALPHA);
                //Update the window
                UpdateWindow();
            }
        }

        public void UpdateWindow()
        {
            //return;
            API.SetWindowPos(loaderHandle, IntPtr.Zero, 0, 0, 0, 0,
                (uint)WM.SWP.SWP_NOACTIVATE | (uint)WM.SWP.SWP_NOMOVE | (uint)WM.SWP.SWP_NOSIZE |
                (uint)WM.SWP.SWP_NOZORDER | (uint)WM.SWP.SWP_NOOWNERZORDER |
                (uint)WM.SWP.SWP_FRAMECHANGED);
        }

        public void ShowWindow(bool mode)
        {
            //return;
            if (mode)
                API.ShowWindow(loaderHandle, 1);
            else
                API.ShowWindow(loaderHandle, 0);
        }

        public void RemoveFromTaskbar()
        {
            //return;
            loaderExStyle = loaderExStyle & (int)~WM.M.WS_EX_APPWINDOW;
            API.SetWindowLong(loaderHandle, (int)WM.M.GWL_EXSTYLE, loaderExStyle);
        }

        public void ApplyImmunity()
        {
            //return;
            //New bot style
            loaderStyle = 0x16010000;
            loaderExStyle = 0x00050000 & (int)~WM.M.WS_EX_APPWINDOW | (int)WM.M.WS_EX_NOACTIVATE;
            //Apply style
            API.SetWindowLong(loaderHandle, (int)WM.M.GWL_STYLE, loaderStyle);
            API.SetWindowLong(loaderHandle, (int)WM.M.GWL_EXSTYLE, loaderExStyle);
        }

        /// <summary>
        /// Capture the raw window through this process. If any dead images are thrown back, filteration will
        /// cause this function to be recalled until a proper image is taken.
        /// </summary>
        /// <returns>Returns the image captured as a bitmap.</returns>
        public Bitmap CaptureRawWindow()
        {
            //Uncomment if you are recieving a high ratio of dead images.
            //System.Threading.Thread.Sleep(100);
            //Make a bitmap object.
            Bitmap bmp = new Bitmap(765, 503);
            //Get graphics
            Graphics graph = Graphics.FromImage(bmp);
            //Get hDC of graphics
            IntPtr hDC = graph.GetHdc();
            //Point hDC to printwindow, so this call can print the window into the bmp.
            API.PrintWindow(loaderHandle, hDC, 0);
            //Release crap
            graph.ReleaseHdc();
            graph.Dispose();
            //Return bmp
            return bmp;
        }
    }
}
